package com.atguigu.gulimall.auth.controller;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberVo;
import com.atguigu.gulimall.auth.feign.MemberFeignService;
import com.atguigu.gulimall.auth.service.LoginService;
import com.atguigu.gulimall.auth.vo.UserLoginVo;
import com.atguigu.gulimall.auth.vo.UserRegistVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Controller
@Slf4j
public class LoginController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private MemberFeignService memberFeignService;

    /**
     * 发送手机验证码
     * @param phone
     * @return
     */
    @ResponseBody
    @GetMapping("/sms/sendCode")
    public R sendCode(@RequestParam("phone") String phone) {
        boolean result = loginService.sendCode(phone);
        if (result == true) {
            return R.ok();
        } else {
            return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(), BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
        }
    }

    /**
     * 新用户注册
     *
     * @param vo
     * @param result
     * @param redirectAttributes model只能用于转发携带数据，重定向携带数据需要使用redirectAttributes
     *                           重定向携带数据，是将数据放在session中，只要跳到下一个页面取出这个数据以后，session里面的数据就会删掉
     * @return
     */
    @PostMapping("/regist")
    public String regist(@Valid UserRegistVo vo, BindingResult result, RedirectAttributes redirectAttributes) {
        Map<String, String> errors = new HashMap<>();
        if (result.hasErrors()) {
            // 参数校验不通过，返回异常信息
            errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }
        boolean checkResult = loginService.checkCode(vo.getPhone(), vo.getCode());
        if (!checkResult) {
            // 验证码过期或验证码输入有误，重新输入
            errors.put("code", "验证码错误，请重新获取验证码后再次输入");
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }
        // 调用会员服务，进行用户注册
        R regist = memberFeignService.regist(vo);
        if (regist.getCode() == 0) {
            // 注册成功，回到登录页
            return "redirect:http://auth.gulimall.com/login.html";
        } else {
            // 用户注册过程出现异常
            String exceptionInfo = regist.getData(String.valueOf(BizCodeEnume.USER_EXIST_EXCEPTION.getCode()),
                    new TypeReference<String>() {
                    });
            errors.put("msg", exceptionInfo);
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }
    }

    /**
     * 用户登录
     * @param vo
     * @return
     */
    @PostMapping("/login")
    public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session) {
        Map<String, String> errors = new HashMap<>();
        // 调用会员服务，进行用户登录
        try {
            R result = memberFeignService.login(vo);
            if (result.getCode() == 0) {
                MemberVo member = result.getData("data", new TypeReference<MemberVo>(){});
                log.info("登录成功，登录用户为：{}", member);
                // 将session信息存到redis中
                session.setAttribute(AuthServerConstant.LOGIN_USER, member);
                // 登录成功，跳转到商城首页
                return "redirect:http://gulimall.com";
            } else {
                // 登录出现异常，返回异常信息
                String exceptionInfo = result.getData(String.valueOf(BizCodeEnume.USER_LOGIN_EXCEPTION.getCode()),
                        new TypeReference<String>() {
                        });
                errors.put("msg", exceptionInfo);
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.gulimall.com/login.html";
            }
        } catch (Exception e) {
            return "redirect:http://auth.gulimall.com/login.html";
        }
    }

    @GetMapping("/login.html")
    public String loginPage(HttpSession session) {
        return session.getAttribute(AuthServerConstant.LOGIN_USER) == null ? "login" : "redirect:http://gulimall.com";
    }
}
